package org.evolAI.organism.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name="Code")
@XmlRootElement
public class Code implements List<Step> {
	
	private long id;
	private List<Step> steps = new ArrayList<Step>();
	
	public Code() {
		
	}
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "code_id")
	public long getId() {
		return this.id;
	}
	
	public void setId(long id) {
		this.id = id;
	}

	 @OneToMany(cascade=CascadeType.ALL)
	 public List<Step> getSteps() {
		return steps;
	}
	
	public void setSteps(List<Step> steps) {
		this.steps = steps;
	}

	protected Code(Code in_code) {
		for (Step step: in_code.steps) {
			steps.add(step.copy());
		}
	}
	
    public Code copy() {
        return new Code(this);
    }

    public Code merge(Code code) {
        Code newCode = new Code();

        //TODO: fill this in

        return newCode;
    }

    @Override
    public int size() {
    	return steps.size();
    }

    @Override
    public Iterator<Step> iterator() {
		return steps.iterator();
	}

    @Override
    @Transient
	public boolean isEmpty() {
		return steps.isEmpty();
	}

    @Override
	public boolean contains(Object o) {
		return steps.contains(o);
	}

    @Override
	public Object[] toArray() {
		return steps.toArray();
	}

    @Override
	public <T> T[] toArray(T[] a) {
		return steps.toArray(a);
	}

    @Override
	public boolean add(Step e) {
		return steps.add(e);
	}

    @Override
	public boolean remove(Object o) {
		return steps.remove(o);
	}

    @Override
	public boolean containsAll(Collection<?> c) {
		return steps.containsAll(c);
	}

    @Override
	public boolean addAll(Collection<? extends Step> c) {
		return steps.addAll(c);
	}

    @Override
	public boolean addAll(int index, Collection<? extends Step> c) {
		return steps.addAll(index, c);
	}

    @Override
	public boolean removeAll(Collection<?> c) {
		return steps.removeAll(c);
	}

    @Override
	public boolean retainAll(Collection<?> c) {
		return steps.retainAll(c);
	}

    @Override
	public void clear() {
    	steps.clear();
	}

    @Override
	public Step get(int index) {
		return steps.get(index);
	}

    @Override
	public Step set(int index, Step element) {
		return steps.set(index, element);
	}

    @Override
	public void add(int index, Step element) {
    	steps.add(index, element);
	}

    @Override
	public Step remove(int index) {
		return steps.remove(index);
	}

    @Override
	public int indexOf(Object o) {
		return steps.indexOf(o);
	}

    @Override
	public int lastIndexOf(Object o) {
		return steps.lastIndexOf(o);
	}

    @Override
	public ListIterator<Step> listIterator() {
		return steps.listIterator();
	}

    @Override
	public ListIterator<Step> listIterator(int index) {
		return steps.listIterator(index);
	}

    @Override
	public List<Step> subList(int fromIndex, int toIndex) {
		return steps.subList(fromIndex, toIndex);
	}

}
